/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * Interfaz.java
 *
 * Created on 24/05/2012, 06:02:45 AM
 */
package ia1_practica3;

import Sockets.HiloCliente;
import Sockets.HiloSer;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import Sockets.*;
import java.io.File;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;

/**
 * 
 * @author Edson Salazar
 */
public class Interfaz extends javax.swing.JFrame {

    HiloSer hiloservidor;
    HiloCliente hilocliente;
    NodoArbol raiz;
    Bitacora bitacora = new Bitacora();
    boolean MODOSERVIDOR = false;
    private Matriz matriz;
    private Casilla casillaSeleccionada;
    private Heuristica movement;
    private HashMap<Integer, Casilla> posiblesMov;
    private ArrayList<Jugada> listaJugadas1;
    private ArrayList<Jugada> listaJugadas2;
    /**
     * Lista general de jugadas hechas por los jugadores
     */
    private ArrayList<Jugada> listaJugadas = new ArrayList<Jugada>();
    private int turno;

    /** Creates new form Interfaz */
    public Interfaz() {
        initComponents();
        inicializar();
    }

    private void inicializar() {
        listaJugadas1 = new ArrayList<Jugada>();
        listaJugadas2 = new ArrayList<Jugada>();
        turno = 2;
        cambiarTurno();

        matriz = new Matriz();
        crearCampoJuego();

        System.out.println("---");
        movement = new Heuristica();
        //movement.posibles_jugadas(matriz, turno, turno);
    }

    private void crearCampoJuego() {
        int ancho = matriz.getAncho();
        int alto = matriz.getAlto();
        int posx = 1, posy = 1;
        int limite = ancho;
        boolean par = true;
        Casilla temp;
        for (int i = 0; i < alto; i++) {
            par = i % 2 == 0;
            posx = par ? 1 : 14;
            limite = par ? ancho : ancho - 1;
            for (int j = par ? 0 : 1; j < limite; j = j + 2) {
                temp = matriz.getCasilla(j, i);
                temp.setLocation(posx, posy);
                panelJuego.add(temp);
                posx += temp.getSize().width;
            }
            posy += 26;
        }
    }

    public Casilla getCasillaSeleccionada() {
        return casillaSeleccionada;
    }

    public void setCasillaSeleccionada(Casilla casillaSeleccionada) {
        if (this.casillaSeleccionada == null) {
            if (casillaSeleccionada.getTipoCasilla() > Casilla.EST_VACIAPRESS && esTurno(casillaSeleccionada.getTipoCasilla())) {
                this.casillaSeleccionada = casillaSeleccionada;
                this.posiblesMov = matriz.getPosiblesMov(casillaSeleccionada.getColumna(),
                        casillaSeleccionada.getFila());
            }
        } else {
            if (casillaSeleccionada == null) {
                this.casillaSeleccionada = null;
            } else {
                if (moverFicha(casillaSeleccionada)) {
                    System.out.println("Se movio la ficha");
                } else {
                    System.out.println("Movimiento inválido");
                }
            }
        }
    }

    public boolean moverFicha(Casilla ficha) {
        boolean exito = false;
        Integer clave = matriz.getClave(ficha);
        Casilla temp;
        Jugada jugada;
        if (posiblesMov.containsKey(clave)) {
            temp = posiblesMov.get(clave);
            if (temp.getColumna() == ficha.getColumna() && temp.getFila() == ficha.getFila()) {
                System.out.println("Se hace el movimiento");
                //Se crea un objeto para llevar registro
                jugada = new Jugada(casillaSeleccionada.getColumna(),
                        casillaSeleccionada.getFila(),
                        ficha.getColumna(), ficha.getColumna(), turno);

                jugada.setJugador(turno);
                listaJugadas.add(jugada);
                if (turno == 1) {
                    this.sendmensaje("Jugador1: " + jugada.getColinicio() + "," + jugada.getFilinicio()
                            + " -> " + jugada.getColfin() + "," + jugada.getFilfin());
                    listaJugadas1.add(jugada);
                } else {
                    this.sendmensaje("Jugador2: " + jugada.getColinicio() + "," + jugada.getFilinicio()
                            + " -> " + jugada.getColfin() + "," + jugada.getFilfin());
                    listaJugadas2.add(jugada);
                }

                sendmensaje(String.valueOf(casillaSeleccionada.getColumna() + "," + casillaSeleccionada.getFila() + ";"
                        + ficha.getColumna() + "," + ficha.getColumna() + ";" + getTurno()));

                //sendmensaje(String.valueOf(casillaSeleccionada.getColumna()+","+ casillaSeleccionada.getFila()+";" 
                //       +ficha.getColumna()+","+ ficha.getColumna()+";"+getTurno()));


                //Se hace el movimiento
                temp.setTipoCasilla(casillaSeleccionada.getTipoCasilla());
                casillaSeleccionada.setTipoCasilla(Casilla.EST_VACIA);
                //Se actualiza la lista de posición de fichas
                switch (turno) {
                    case 1:
                        matriz.getListaFichas1().remove(casillaSeleccionada);
                        matriz.getListaFichas1().add(temp);
                        break;
                    case 2:
                        matriz.getListaFichas2().remove(casillaSeleccionada);
                        matriz.getListaFichas2().add(temp);
                        break;
                }
                //Se actualiza el puntero hacia la casilla seleccionada
                casillaSeleccionada = temp;
                //Se generan las posibles movimientos de nuevo
                this.posiblesMov = matriz.getPosiblesMov(casillaSeleccionada.getColumna(),
                        casillaSeleccionada.getFila());
                return true;
            } else {
                //Si no. se notifica el movimiento inválido
                System.out.println("Movimiento invalido");
            }
        }
        return exito;
    }

    public void insertlista(Jugada jugada) {
        listaJugadas.add(jugada);
    }

    private void cambiarTurno() {
        if (casillaSeleccionada != null) {
            if (casillaSeleccionada.getTipoCasilla() % 2 == 1) {
                casillaSeleccionada.setTipoCasilla(casillaSeleccionada.getTipoCasilla() - 1);
                casillaSeleccionada = null;
            }
        }
        switch (turno) {
            case 1:
                this.sendmensaje("Es turno del jugador 2");
                lblTurno.setIcon(new javax.swing.ImageIcon(getClass().getResource("/img/azul0.jpg")));
                lblTurno.setText("Jugador 2");
                turno = 2;
                break;
            case 2:
                this.sendmensaje("Es turno del jugador 1");
                lblTurno.setIcon(new javax.swing.ImageIcon(getClass().getResource("/img/rojo0.jpg")));
                lblTurno.setText("Jugador 1");
                turno = 1;
                break;
        }

    }

    /**
     * Indica si en el momento de la consulta la casilla se 
     * encuentra en su turno
     * @param casilla
     * @return 
     */
    public boolean esTurno(int tipoCasilla) {
        switch (turno) {
            case 1:
                return (tipoCasilla == Casilla.EST_JUGADOR1 || tipoCasilla == Casilla.EST_JUGADOR1PRESS);
            case 2:
                return (tipoCasilla == Casilla.EST_JUGADOR2 || tipoCasilla == Casilla.EST_JUGADOR2PRESS);
            default:
                return false;
        }
    }

    public int getTurno() {
        return turno;
    }

    public ArrayList<Jugada> getListaJugadas() {
        return listaJugadas;
    }

    public void mover_ficha_computadora() {

        //movement.posibles_jugadas(matriz, 11, 3);
        //movement.posibles_jugadas(matriz, 9, 3);

        for (int i = 0; i < matriz.getListaFichas1().size(); i++) {
            matriz.getListaFichas1().get(i).getColumna();
            System.out.println(matriz.getListaFichas1().get(i).getColumna() + "--*-*/*/--/--" + matriz.getListaFichas1().get(i).getFila());
        }
        System.out.println("*/***************************//*");
        for (int i = 0; i < matriz.getListaFichas2().size(); i++) {
            matriz.getListaFichas2().get(i).getColumna();
            System.out.println(matriz.getListaFichas2().get(i).getColumna() + "--*/*//*/--" + matriz.getListaFichas2().get(i).getFila());
            movement.posibles_jugadas(i, matriz, matriz.getListaFichas2().get(i).getColumna(), matriz.getListaFichas2().get(i).getFila());
        }
        Jugada jugada = movement.busquedas();

        if (jugada != null) {
            jugada.setJugador(turno);
            listaJugadas.add(jugada);
            if (turno == 1) {
                this.sendmensaje("Jugador1: " + jugada.getColinicio() + "," + jugada.getFilinicio()
                        + " -> " + jugada.getColfin() + "," + jugada.getFilfin());
                listaJugadas1.add(jugada);
            } else {
                this.sendmensaje("Jugador2: " + jugada.getColinicio() + "," + jugada.getFilinicio()
                        + " -> " + jugada.getColfin() + "," + jugada.getFilfin());
                listaJugadas2.add(jugada);
            }
        }
    }

    public void servidor() {
        hiloservidor = new HiloSer();
        menucliente.setEnabled(false);
        menuserver.setEnabled(false);
        menuIP.setEnabled(true);
    }

    public void cliente() {
        String IPServidor = "";
        String[] array;
        IPServidor = javax.swing.JOptionPane.showInputDialog(this, "Ingrese la IP del server");
        if (IPServidor != null) {
            System.out.println("IP: " + IPServidor);
            array = IPServidor.replace(".", ":").split(":");
            System.out.println("Length " + array.length);
            if (array.length == 4) {
                hilocliente = new HiloCliente(IPServidor);
                menucliente.setEnabled(false);
                menuserver.setEnabled(false);
            } else {
                javax.swing.JOptionPane.showMessageDialog(this, "La IP ingresada no es válida");
            }
        }
    }

    public void sendmensaje(String envio) {
        addLog(envio);
        if (hiloservidor != null) {

            if (this.MODOSERVIDOR) {
                this.hiloservidor.sendmensaje(envio);
            } else {
                this.hilocliente.sendmessage(envio);
            }
        }
    }

    public void addLog(String mensaje) {
        areaChat.setText(areaChat.getText() + "\n" + mensaje);
    }

    public void get_bitacora() {
        JFileChooser abrir = new JFileChooser();
        abrir.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        int seleccion = abrir.showOpenDialog(this);
        if (seleccion == JFileChooser.APPROVE_OPTION) {
            bitacora.creacion(abrir.getSelectedFile(), listaJugadas);

        }
    }
    
    private String getIP(){
        // IP en formato String
        String IP = "";
        try {
            java.net.InetAddress address = java.net.InetAddress.getLocalHost();
            // Cogemos la IP
            byte[] bIPAddress = address.getAddress();
            for (int x = 0; x < bIPAddress.length; x++) {
                if (x > 0) {
                    // A todos los numeros les anteponemos
                    // un punto menos al primero
                    IP += ".";
                }
                // Jugamos con los bytes y cambiamos el bit del signo
                IP += bIPAddress[x] & 255;
            }
        } catch (UnknownHostException ex) {
            javax.swing.JOptionPane.showMessageDialog(this, "Error  "+ex.getMessage());
        }
        return IP;
    }

    private void enviarChat() {
        String texto = this.txtChat.getText();
        sendmensaje(texto);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        panelJuego = new javax.swing.JPanel();
        panelControles = new javax.swing.JPanel();
        lblTituloTurno = new javax.swing.JLabel();
        lblTurno = new javax.swing.JLabel();
        btnFinalizarTurno = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        areaChat = new javax.swing.JTextArea();
        btnEnviar = new javax.swing.JButton();
        txtChat = new javax.swing.JTextField();
        lblIngresoTexto = new javax.swing.JLabel();
        jMenuBar1 = new javax.swing.JMenuBar();
        menuArchivo = new javax.swing.JMenu();
        menubitacora = new javax.swing.JMenuItem();
        menuserver = new javax.swing.JMenuItem();
        menucliente = new javax.swing.JMenuItem();
        menuSalir = new javax.swing.JMenuItem();
        menuVer = new javax.swing.JMenu();
        menuIP = new javax.swing.JMenuItem();
        menuAyuda = new javax.swing.JMenu();
        menuManualUsuario = new javax.swing.JMenuItem();
        menuAcercaDe = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        panelJuego.setMinimumSize(new java.awt.Dimension(340, 445));
        panelJuego.setPreferredSize(new java.awt.Dimension(431, 650));

        javax.swing.GroupLayout panelJuegoLayout = new javax.swing.GroupLayout(panelJuego);
        panelJuego.setLayout(panelJuegoLayout);
        panelJuegoLayout.setHorizontalGroup(
            panelJuegoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 340, Short.MAX_VALUE)
        );
        panelJuegoLayout.setVerticalGroup(
            panelJuegoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 447, Short.MAX_VALUE)
        );

        panelControles.setBorder(javax.swing.BorderFactory.createTitledBorder("Controles"));
        panelControles.setPreferredSize(new java.awt.Dimension(150, 445));

        lblTituloTurno.setText("Turno actual");

        lblTurno.setText("Turno Jugador 1");

        btnFinalizarTurno.setText("Finalizar Turno");
        btnFinalizarTurno.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnFinalizarTurnoActionPerformed(evt);
            }
        });

        areaChat.setColumns(15);
        areaChat.setEditable(false);
        areaChat.setRows(5);
        jScrollPane1.setViewportView(areaChat);

        btnEnviar.setText("Enviar");
        btnEnviar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnEnviarActionPerformed(evt);
            }
        });

        lblIngresoTexto.setText("Ingreso de texto:");

        javax.swing.GroupLayout panelControlesLayout = new javax.swing.GroupLayout(panelControles);
        panelControles.setLayout(panelControlesLayout);
        panelControlesLayout.setHorizontalGroup(
            panelControlesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(btnEnviar, javax.swing.GroupLayout.DEFAULT_SIZE, 138, Short.MAX_VALUE)
            .addComponent(txtChat, javax.swing.GroupLayout.DEFAULT_SIZE, 138, Short.MAX_VALUE)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 138, Short.MAX_VALUE)
            .addGroup(panelControlesLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(panelControlesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(lblTurno, javax.swing.GroupLayout.DEFAULT_SIZE, 118, Short.MAX_VALUE)
                    .addComponent(lblTituloTurno)
                    .addGroup(panelControlesLayout.createSequentialGroup()
                        .addComponent(btnFinalizarTurno)
                        .addGap(0, 15, Short.MAX_VALUE))
                    .addGroup(panelControlesLayout.createSequentialGroup()
                        .addComponent(lblIngresoTexto, javax.swing.GroupLayout.PREFERRED_SIZE, 103, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(0, 15, Short.MAX_VALUE)))
                .addContainerGap())
        );
        panelControlesLayout.setVerticalGroup(
            panelControlesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panelControlesLayout.createSequentialGroup()
                .addComponent(lblTituloTurno)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(lblTurno, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(20, 20, 20)
                .addComponent(btnFinalizarTurno)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE)
                .addGap(18, 18, 18)
                .addComponent(lblIngresoTexto)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(txtChat, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnEnviar))
        );

        menuArchivo.setText("Archivo");

        menubitacora.setText("Bitacora");
        menubitacora.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menubitacoraActionPerformed(evt);
            }
        });
        menuArchivo.add(menubitacora);

        menuserver.setText("Server");
        menuserver.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuserverActionPerformed(evt);
            }
        });
        menuArchivo.add(menuserver);

        menucliente.setText("Cliente");
        menucliente.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuclienteActionPerformed(evt);
            }
        });
        menuArchivo.add(menucliente);

        menuSalir.setText("Salir");
        menuSalir.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuSalirActionPerformed(evt);
            }
        });
        menuArchivo.add(menuSalir);

        jMenuBar1.add(menuArchivo);

        menuVer.setText("Ver");

        menuIP.setText("Dirección IP");
        menuIP.setEnabled(false);
        menuIP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuIPActionPerformed(evt);
            }
        });
        menuVer.add(menuIP);

        jMenuBar1.add(menuVer);

        menuAyuda.setText("Ayuda");

        menuManualUsuario.setText("Manual de Usuario");
        menuAyuda.add(menuManualUsuario);

        menuAcercaDe.setText("Acerca de...");
        menuAyuda.add(menuAcercaDe);

        jMenuBar1.add(menuAyuda);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(panelJuego, javax.swing.GroupLayout.DEFAULT_SIZE, 340, Short.MAX_VALUE)
                .addGap(18, 18, 18)
                .addComponent(panelControles, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(panelJuego, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 447, Short.MAX_VALUE)
                    .addComponent(panelControles, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 447, Short.MAX_VALUE))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void btnFinalizarTurnoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFinalizarTurnoActionPerformed
        this.cambiarTurno();
        if (turno == 2) {
            mover_ficha_computadora();
            this.cambiarTurno();
        }
    }//GEN-LAST:event_btnFinalizarTurnoActionPerformed

    private void menuserverActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuserverActionPerformed
        servidor();
    }//GEN-LAST:event_menuserverActionPerformed

    private void menuclienteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuclienteActionPerformed
        cliente();        // TODO add your handling code here:
    }//GEN-LAST:event_menuclienteActionPerformed

    private void menubitacoraActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menubitacoraActionPerformed
        get_bitacora();
    }//GEN-LAST:event_menubitacoraActionPerformed

    private void menuSalirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuSalirActionPerformed
        int respuesta = javax.swing.JOptionPane.showConfirmDialog(this,
                "¿Desea finalizar la aplicación?", "Confirmar",
                javax.swing.JOptionPane.YES_NO_OPTION);
        if (respuesta == javax.swing.JOptionPane.YES_OPTION) {
            System.exit(0);
        }
    }//GEN-LAST:event_menuSalirActionPerformed

    private void btnEnviarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnEnviarActionPerformed
        enviarChat();
    }//GEN-LAST:event_btnEnviarActionPerformed

    private void menuIPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuIPActionPerformed
        javax.swing.JOptionPane.showMessageDialog(this, "La IP es: "+this.getIP());
    }//GEN-LAST:event_menuIPActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextArea areaChat;
    private javax.swing.JButton btnEnviar;
    private javax.swing.JButton btnFinalizarTurno;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JLabel lblIngresoTexto;
    private javax.swing.JLabel lblTituloTurno;
    private javax.swing.JLabel lblTurno;
    private javax.swing.JMenuItem menuAcercaDe;
    private javax.swing.JMenu menuArchivo;
    private javax.swing.JMenu menuAyuda;
    private javax.swing.JMenuItem menuIP;
    private javax.swing.JMenuItem menuManualUsuario;
    private javax.swing.JMenuItem menuSalir;
    private javax.swing.JMenu menuVer;
    private javax.swing.JMenuItem menubitacora;
    private javax.swing.JMenuItem menucliente;
    private javax.swing.JMenuItem menuserver;
    private javax.swing.JPanel panelControles;
    private javax.swing.JPanel panelJuego;
    private javax.swing.JTextField txtChat;
    // End of variables declaration//GEN-END:variables
}
